// package main

// import "fmt"

// type ByteCounter int

// func (c *ByteCounter) Write(p []byte) (int, error) {
// 	*c += ByteCounter(len(p))
// 	return len(p), nil
// }

// func main() {
// 	var c ByteCounter

// 	c.Write([]byte("hello"))
// 	fmt.Println(c)
// 	c = 0
// 	var name = "Dolly"
// 	fmt.Fprintf(&c, "hello %s", name)
// 	fmt.Println(c)
// }

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"

	"golang.org/x/net/html"
)

type ByteCouner int

func (c *ByteCouner) Write(words []byte) (int, error) {
	(*c) += ByteCouner(len(words))

	return len(words), nil
}

func countwords() {
	in := bufio.NewScanner(os.Stdin)
	in.Split(bufio.ScanWords)
	var c ByteCouner
	c = 0

	for in.Scan() {
		line := in.Text()
		fmt.Fprintf(&c, line)
	}
	fmt.Println(c)
}

func countline() {
	in := bufio.NewScanner(os.Stdin)

	var c ByteCouner
	c = 0

	for in.Scan() {
		line := in.Text()
		fmt.Fprintf(&c, line)
	}
	fmt.Println(c)
}

type CounterWriter struct {
	writer io.Writer
	count  int
}

func (c *CounterWriter) Write(p []byte) (int, error) {
	c.count += len(p)
	return c.count, nil
}

func CountingWriter(w io.Writer) (io.Writer, *int) {
	cw := CounterWriter{writer: w}
	return &cw, &cw.count
}

type HttpReader struct {
	str   string
	count int64
}

func (h *HttpReader) Read(p []byte) (int, error) {
	if int(h.count) >= len(p) {
		return -1, io.EOF
	}

	n := copy(p, h.str[h.count:])
	return n, nil
}

func NewReader(s string) io.Reader {
	return &HttpReader{str: s, count: 0}
}

func Test2() {

	htmlString := `
        <html>
            <body>
                <h1>Hello, World!</h1>
                <p>This is a test paragraph.</p>
            </body>
        </html>
    `
	reader := NewReader(htmlString)

	doc, err := html.Parse(reader)
	if err != nil {
		panic(err)
	}

	fmt.Println("HTML, parsed successfully!")

	var f func(*html.Node)
	f = func(n *html.Node) {
		if n.Type == html.ElementNode {
			fmt.Println("Element:", n.Data)
		}
		for c := n.FirstChild; c != nil; c = c.Nextsibling {
			f(c)
		}
	}
	f(doc)
}

type MyReader struct {
	bs    []byte
	count int
}

func (r *MyReader) Read(p []byte) (int, error) {
	if r.count > len(r.bs) {
		return -1, io.EOF
	}

	n := copy(p, r.bs[r.count:])
	return n, nil
}

type limitReader struct {
	r     io.Reader
	count int64
}

func (l *limitReader) Read(p []byte) (int, error) {
	if l.count < 0 {
		return 0, io.EOF
	}

	if int64(len(p)) > l.count {
		p = p[:l.count]
	}
	n, err := l.r.Read(p)
	l.count -= int64(n)
	return n, err
}

func LimitReader(r io.Reader, n int64) io.Reader {
	return &limitReader{r: r, count: n}
}
